/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 * 
 * Copyright (c) 2008-2009, The KiWi Project (http://www.kiwi-project.eu)
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without 
 * modification, are permitted provided that the following conditions are met:
 * - Redistributions of source code must retain the above copyright notice, 
 *   this list of conditions and the following disclaimer.
 * - Redistributions in binary form must reproduce the above copyright notice, 
 *   this list of conditions and the following disclaimer in the documentation 
 *   and/or other materials provided with the distribution.
 * - Neither the name of the KiWi Project nor the names of its contributors 
 *   may be used to endorse or promote products derived from this software 
 *   without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE 
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 
 * POSSIBILITY OF SUCH DAMAGE.
 * 
 * Contributor(s):
 * 
 * 
 */
package kiwi.social.api.tagging;

import kiwi.core.model.rdf.KiWiResource;
import kiwi.core.model.user.KiWiUser;
import kiwi.social.model.tagging.Tag;
import kiwi.social.model.tagging.Tagging;

import java.util.List;
import java.util.Set;

/**
 * A DAO service for managing tags. Provides convenience methods for creating new tags, modifying
 * tags, and removing tags.
 * 
 * @author Sebastian Schaffert
 *
 */
public interface TaggingService {

    /* ********************************************************************************************
     * Methods to work with Taggings, i.e. the individual tagging activities
     * ******************************************************************************************** */


	/**
	 * Create a new tagging of taggedItem with taggingItem based on the given label for taggingUser.
	 * This method creates a new tag instance with a generated, unique uri resource. The tag is then
	 * persisted in the entityManager and tripleStore, and returned to the caller.
	 * 
	 * @param label a textual label of the tagging; this is usually the string entered by the user
	 *              which has then been used to look up taggingItem
	 * @param taggedItem the tagged content item
	 * @param taggingItem the content item used as tag
	 * @param taggingUser the user who performed the tagging
	 * @return the newly created and persisted tag
	 */
	public Tagging createTagging(String label, KiWiResource taggedItem, KiWiResource taggingItem, KiWiUser taggingUser);
	

    /**
      * Create taggings for a contentItem <code>item</code> with the taggingContentItem
      * having the label <code>label</code>. If a contentItem with the label already exists,
      * it will be reused, otherwise freshly created.
      *
     * @param item
     * @author szabyg
      */
     public Tagging createTagging(KiWiResource item, String tagLabel, KiWiUser user);



    /**
     * List the taggings associated with a content item. This method is safer than getTags of
     * ContentItem, because it avoids the detached entity problem...
     *
     * @param resource
     * @return
     */
    public List<Tagging> getTaggingsByItem(KiWiResource resource);


    /**
     * Return tags by a given user
     * @param currentUser
     * @return
     */
    public List<Tagging> getTaggingsByUser(KiWiUser currentUser);


    /**
     * Remove an existing tagging from the database.
     *
     * @param tagging the tagging to remove
     */
    public void removeTagging(KiWiResource tagging);



    /**
     * Create taggings for a contentItem <code>item</code> with the taggingContentItem
     * having the label <code>label</code>. If a contentItem with the label already exists,
     * it will be reused, otherwise freshly created.
     * @param item
     * @author szabyg
     */
    public void addTags(KiWiResource item, String[] tagLabels, KiWiUser user);


    /**
     *
     * @param item
     * @param tagLabel
     * @param user
     */
    public void removeTagging(KiWiResource item, String tagLabel, KiWiUser user);

    /*
    * Delete taggings for a ContentItem <code>item</code> with the ContentItems with the labels in the String[] tagLabels.
    * @param item
    * @param shared
    * @author szabyg
    */
    public void removeTags(KiWiResource item, String[] tagLabels, KiWiUser user);


    /* ********************************************************************************************
     * Methods to work with Tags, i.e. resources that are used as tags of other resources
     * ******************************************************************************************** */

    /**
     * Creeate a new resource that represents a tag and has the specified label- The label will be stored
     * using the hgtags:name and rdfs:label and kiwi:title properties.
     *
     * @param label
     * @return
     */
    public Tag createTag(String label);

    /**
     * Turn the resource passed as parameter into the tag with the specified label. The label will be stored using
     * the hgtags:name and rdfs:label and kiwi:title properties.
     *
     * @param r the resource around which to create the tag
     * @param label
     * @return
     */
    public Tag createTag(KiWiResource r, String label);


    /**
     * Return the tag identified by the given URI, or null if it does not exist.
     *
     * @param uri a URI identifying the resource that represents the tag to be returned
     * @return
     */
    public Tag getTag(String uri);


    /**
     * Get all tags with the specified label. Queries the hgtags:name property.
     */
    public List<Tag> getTagsByLabel(String label);



	/**
	 * Verify whether the given label has been associated with the content item.
	 * 
	 * @param taggedItem the content item that has been tagged
	 * @param label the label used for tagging
	 * @return true if the label was used for tagging the item.
	 */
	public boolean hasTag(KiWiResource taggedItem, String label);



    /**
     * Return all tags stored in the KiWi system.
     *
     * @return
     */
    public List<Tag> getAllTags();

    /**
     * Return all tags that are not SKOS concepts within a hierarchy (i.e. have neither broader nor narrower concepts)
     *
     * @return
     */
    public List<Tag> getFreeTags();


    /**
     * Return all tags that are SKOS concepts within a hierarchy (i.e. have either broader or narrower concepts)
     *
     * @return
     */
    public List<Tag> getControlledTags();

	/**
	 * Get the content items used as tags for the given content item. This method performs an
	 * aggregation over all taggings grouped by taggingResource.
	 * 
	 * @param item
	 * @return
	 */
	public List<Tag> getTags(KiWiResource item);
	
	

	

	/**
	/**
	 * Counts the current usages of a tag, meaning, how many ContentItems are tagged with the tag.
	 * @param resource
	 * @return
	 * @author szabyg
	 */
	public Long getTagUsage(KiWiResource resource);



	/**
	 * List all content items tagged with a certain item given as argument. May make use 
	 * of either database queries or the search service.
	 * 
	 * @param tag
	 * @return
	 */
	public Set<KiWiResource> getTaggedItems(KiWiResource tag);



	/**
	 * List the users that are using the content item passed as argument in tagging 
	 * activities.
	 * 
	 * @param tag
	 * @return
	 */
	public Set<KiWiUser> getTagUsers(KiWiResource tag);
	

}
